今天我們將透過click
事件中的shift
屬性以及陣列的觀念,來做出選取多個項目的功能。在作者的範例中,當勾選其中一個欄位之後,按著Shift再勾選任一一個欄位,這之間的每個欄位都會被勾選起來。[1]
實作連結
要完成今天的目標,我們要依序完成幾樣事情:
首先我們將每個勾選欄位都加上監聽click
事件,且透過console.log(event)
,我們可以發現click
事件中包含了一個屬性shiftKey
。透過這個屬性我們就能得知按下滑鼠的同時,shift按鍵是否也被按下,因此不需再額外監聽鍵盤的事件:
//選取所有的input元素
let checkInput = document.querySelectorAll('input');
//透過forEach方法將每個input元素加上監聽事件
checkInput.forEach(function (input) {
input.addEventListener('click', selectMany);
});
將前面因選取所有input
元素而產生的NodeList
物件,利用Array.from()
方法轉為陣列,我們就能透過事件觸發時的event.target
加上array.indexOf()
來取得勾選欄的index。
//將NodeList物件轉為陣列
let InputArray = Array.from(checkInput);
//指定初始的勾選位置為0
let lastOrder = 0;
function selectMany(e) {
//取得事件觸發的元素
var test = e.target;
//取得事件觸發的元素位置
var checkOrder = InputArray.indexOf(test);
//如果事件中包含shiftKey,執行check()函式
if (e.shiftKey === true) {
checked(checkOrder);
};
//將這次的位置,指定為下次的起始位置
lastOrder = checkOrder;
};
我們已經指定好符合條件時的函示checked()
並引入代表後來勾選位置的參數值checkOrder
,雖然已得知前後兩次的勾選位置,但我們無法確定每次的後一定都大於前值。因此在我們執行勾選的函式中,需要先判斷兩者的大小關係,之後再由小至大將之間的元素都勾選起來,就能完成今天的課題:
function checked(checkOrder) {
//當後面勾選的位置 > 前面勾選的位置
if (checkOrder > lastOrder) {
//利用for迴圈由小到大取出之間的每個元素
for (i = lastOrder; i < checkOrder; i++) {
//之間的每個input元素設為勾選
checkInput[i].checked = true;
};
};
//當前面勾選的位置 > 後面勾選的位置
} else {
for (i = checkOrder; i < lastOrder; i++) {
checkInput[i].checked = true;
};
};
};
今天也是透過將取得的資料轉為陣列,再透過陣列的相關方法,取得我們DOM上的元素結點並加以應用。可以看到實作上有許多會應用到陣列的地方,如果能熟悉各種陣列方法,之後在資料處理方面將能夠更加的靈活。以上是今天的方法與心得,感謝您的閱讀。